using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Web;
using miPics.Common;
using miPics.Rss;


public partial class _Administration_CreateImage : miPics.BasePage.BasePage
{
	private bool ValidGallery = false;
	private short GalleryID;

	protected void Page_Load(object sender, EventArgs e)
	{
		// set menu administration task
		Master.SetMenuAdministrationTask("Add new image");

		// load gallery we are adding the image to
		this.GalleryID = ToolKit.ReturnShort(Request.QueryString["id"]);

		// get gallery details into datatable
		miPicsDataAccessTableAdapters.GalleryItemTableAdapter GalleryItemTableAdapter = new miPicsDataAccessTableAdapters.GalleryItemTableAdapter();
		miPicsDataAccess.GalleryItemDataTable GalleryItemDataTable = GalleryItemTableAdapter.GetData(this.GalleryID,this.IsLoggedIn);

		// setup admin screen interface
		this.GalleryLoaded = (GalleryItemDataTable.Count == 1);

		if (GalleryItemDataTable.Count == 1) {
			this.ValidGallery = true;

			// place gallery record into item row object
			miPicsDataAccess.GalleryItemRow GalleryItemRow = (miPicsDataAccess.GalleryItemRow)GalleryItemDataTable.Rows[0];

			// pass gallery name back to interface
			_GalleryName.InnerText = GalleryItemRow.Name;
		}
	}

	protected void UploadImage(object sender, EventArgs e)
	{
		if (this.ValidGallery)
		{
			Bitmap UploadedImage = null;

			// was a file posted?
			if (_ImageFile.PostedFile.ContentLength > 0)
			{
				try
				{
					// load uploaded file stream into bitmap object
					UploadedImage = new Bitmap(_ImageFile.PostedFile.InputStream);
				}
				catch
				{
					// image invalid
					UploadedImage = null;

					_FormErrorList.AddError("Uploaded image is invalid");
				}
			}
			else
			{
				// no file posted
				_FormErrorList.AddError("No image selected for upload");
			}

			if (UploadedImage != null)
			{
				// work out the image folder
				string ImageFolderBase = Request.PhysicalApplicationPath + "_Resource\\Image\\";

				// crate new image record and save the new image id
				miPicsDataAccessTableAdapters.ImageItemTableAdapter ImageItem = new miPicsDataAccessTableAdapters.ImageItemTableAdapter();

				short NewImageID =
					(short)ImageItem.CreateItem(
						this.GalleryID,
						ToolKit.TrimToLength(_ImageName.Value, 100),
						_ImageEnabled.Checked,
						ToolKit.TrimToLength(_ImageDescription.Value, 1000));

				// work out the filenames for the images
				string NewImageIDFileBased = NewImageID.ToString().PadLeft(8, '0');
				string ThumbnailFilename = NewImageIDFileBased + "-thumbnail.jpg";
				string FullsizeFilename = NewImageIDFileBased + "-fullsize.jpg";

				// save thumbnail image
				ImageDimensions ThumbnailImage =
						this.CalcImageResize(
							UploadedImage.Width,
							UploadedImage.Height,
							Config.Image.WidthThumbnail,
							Config.Image.HeightThumbnail);

				this.SaveResizedJPEG(
					UploadedImage,
					ThumbnailImage.Width,
					ThumbnailImage.Height,
					Config.Image.QualityThumbnail,
					ImageFolderBase + ThumbnailFilename);

				// save fullsize image
				ImageDimensions FullSizeImage =
						this.CalcImageResize(
							UploadedImage.Width,
							UploadedImage.Height,
							Config.Image.Width,
							Config.Image.Height);

				this.SaveResizedJPEG(
					UploadedImage,
					FullSizeImage.Width,
					FullSizeImage.Height,
					Config.Image.Quality,
					ImageFolderBase + FullsizeFilename);

				// free uploaded image object
				UploadedImage.Dispose();

				// update image record with saved image details
				ImageItem.UpdateItem(
					NewImageID,
					null, null, null, null,
					ThumbnailFilename, (short)ThumbnailImage.Width, (short)ThumbnailImage.Height,
					FullsizeFilename, (short)FullSizeImage.Width, (short)FullSizeImage.Height);

				// update gallery rss
				WriteRss GalleryRss = new WriteRss(this.Request);
				GalleryRss.SaveRss();

				// all done, redirect back to gallery
				Response.Redirect("~/Gallery/?id=" + this.GalleryID);
			}
		}
	}

	protected void CancelUpload(object sender, EventArgs e)
	{
		// redirect back to the gallery
		Response.Redirect("~/Gallery/?id=" + this.GalleryID);
	}

	private bool GalleryLoaded
	{
		set
		{
			_ErrorMessage.Visible = !value;
			_Interface.Visible = value;
		}
	}

	#region Image Saving Routines
	private void SaveResizedJPEG(Bitmap UploadedImage, short ImageWidth, short ImageHeight, short ImageQualityRatio, string ImageFilename)
	{
		// create output image canvas
		Bitmap OutputImage = new Bitmap(UploadedImage, ImageWidth, ImageHeight);

		// create resizer to draw uploaded image onto canvas
		Graphics Resizer = Graphics.FromImage(OutputImage);
		Resizer.CompositingQuality = CompositingQuality.HighQuality;
		Resizer.SmoothingMode = SmoothingMode.HighQuality;
		Resizer.InterpolationMode = InterpolationMode.HighQualityBicubic;

		// draw uploaded image onto canvas resized
		Resizer.DrawImage(UploadedImage, new Rectangle(0, 0, ImageWidth, ImageHeight));

		// setup image save encoder parameters to control quality of output JPEG
		EncoderParameters ImageCodecParams = new EncoderParameters(1);
		ImageCodecParams.Param[0] = new EncoderParameter(Encoder.Quality, (long)ImageQualityRatio);

		// save image to disk, passing image codec info and parameters
		OutputImage.Save(ImageFilename, this.GetImageCodecInfo(), ImageCodecParams);

		// clean up
		ImageCodecParams.Dispose();
		Resizer.Dispose();
		OutputImage.Dispose();
	}

	private ImageCodecInfo GetImageCodecInfo()
	{
		ImageCodecInfo[] Encoders = ImageCodecInfo.GetImageEncoders();

		for (int EncoderCount = 0; EncoderCount < Encoders.Length; EncoderCount++)
			if (Encoders[EncoderCount].MimeType == "image/jpeg")
				return Encoders[EncoderCount];

		return null;
	} 
	#endregion

	#region Image Dimension Calculator
	private ImageDimensions CalcImageResize(int SourceWidth, int SourceHeight, short TargetWidth, short TargetHeight)
	{
		// work out the target width/height dimensions of our image - maintaining aspect ratio
		float ImageWidthRatio = (float)TargetWidth / (float)SourceWidth;

		ImageDimensions CalcImageSize;

		// should our resize be based on the width or the height of the source image?
		if ((int)(SourceHeight * ImageWidthRatio) <= TargetHeight)
		{
			// base it off the width
			CalcImageSize.Height = (short)Math.Ceiling(SourceHeight * ImageWidthRatio);
			if (CalcImageSize.Height > TargetHeight) CalcImageSize.Height = TargetHeight;

			CalcImageSize.Width = TargetWidth;
		}
		else
		{
			// base it off the height
			float ImageHeightRatio = (float)TargetHeight / (float)SourceHeight;

			CalcImageSize.Width = (short)Math.Ceiling(SourceWidth * ImageHeightRatio);
			if (CalcImageSize.Width > TargetWidth) CalcImageSize.Width = TargetWidth;

			CalcImageSize.Height = TargetHeight;
		}

		return CalcImageSize;
	}

	private struct ImageDimensions
	{
		public short Width;
		public short Height;
	} 
	#endregion
}